import Ajv from "ajv";
import addFormats from "ajv-formats";
import addErrors from "ajv-errors";
import { isValidObjectId } from "mongoose";

import Model from "../model";
type models = keyof typeof Model;

export const ajv = new Ajv({ allErrors: true, coerceTypes: true });
addFormats(ajv);
addErrors(ajv);

ajv.addKeyword({
  keyword: "isNotEmpty",
  type: "string",
  validate: function (_: any, data: any) {
    return typeof data === "string" && data.trim() !== "";
  },
  error: {
    message: cxt => {
      const errorProp = cxt.it.errorPath.str.slice(2, -1);
      return `${errorProp} 不能为空`;
    }
  },
  errors: false
});

ajv.addKeyword({
  keyword: "isValidObjectId",
  type: "string",
  validate: (_: any, data: any) => {
    return typeof data === "string" && isValidObjectId(data);
  },
  error: {
    message: cxt => {
      const errorProp = cxt.it.errorPath.str.slice(2, -1);
      return `${errorProp} 不是有效的 ObjectID`;
    }
  },
  errors: false
});

// 传一个 [models, key] 数组
ajv.addKeyword({
  keyword: "isExist",
  type: "string",
  schemaType: "array",
  validate: (schema: [models, string], data: string) => {
    let flag = false;
    Model[schema[0]]
      .findOne({ [schema[1]]: data })
      .select(schema[1])
      .exec((err: any, doc: any) => {
        if (err) flag = true;
        if (!doc) flag = true;
      });
    return flag;
  }
});

ajv.addKeyword({
  keyword: "isNotExist",
  type: "string",
  schemaType: "array",
  validate: (schema: [models, string], data: string) => {
    let flag = true;
    Model[schema[0]]
      .findOne({ [schema[1]]: data })
      .select(schema[1])
      .exec((err: any, doc: any) => {
        if (err) flag = false;
        if (!doc) flag = false;
      });
    return flag;
  }
});
